<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>toRaw与markRaw</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/vue/3.2.40/vue.global.js"></script>
  </head>
  <body>
    <div id="app">
      <p>state.name: {{state.name}}</p>
      <p>state.addr.city: {{state.addr.city}}</p>
      <button @click="test1">测试toRaw</button>
      <hr />
      <p>state2.name: {{state2.name}}</p>
      <p>state2.addr.city: {{state2.addr.city}}</p>
      <button @click="test2">测试markRaw</button>
    </div>
    <script>
      const { createApp, reactive, toRaw, markRaw } = Vue
      createApp({
        setup() {
          // 定义reactive对象
          const state = reactive({
            name: '张三',
            addr: {
              city: '北京',
            },
          })

          // 测试使用toRaw
          const test1 = () => {
            // 通过toRaw得到reactive对象内部包含的原始对象
            const rawPerson = toRaw(state)
            console.log(rawPerson)
          }

          // 原始对象
          const person2 = {
            name: '李四',
            addr: {
              city: '上海',
            },
          }

          // 标记一个原始对象为不可以reactive的对象，并返回这个对象
          const markPerson2 = markRaw(person2)
          console.log(markPerson2) // 多了一个__v_skip为true的属性

          // 对markRaw的对象进行reactive处理，会被原样返回，它不是响应式的
          const state2 = reactive(markPerson2)
          console.log(state2)
          console.log(markPerson2 === person2, state2 === markPerson2)

          // 测试更新markRaw的reactive对象，界面不会更新
          const test2 = () => {
            state2.name += '--'
            state2.addr.city += '--'
            console.log(state2.name, state2.addr.city)
          }

          return {
            state,
            state2,
            test1,
            test2,
          }
        },
      }).mount('#app')
    </script>
  </body>
</html>
